package com.zatech.cgnci.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zatech.cgnci.project.base.utils.BeanUtils;
import com.zatech.cgnci.project.base.utils.ConvertUtils;
import com.zatech.cgnci.project.base.utils.VerifyUtils;
import com.zatech.cgnci.project.entity.*;
import com.zatech.cgnci.project.mapper.CgnciReinsurerMapper;
import com.zatech.cgnci.project.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zatech.cgnci.project.vo.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 再保人信息表 服务实现类
 * </p>
 *
 * @author Generator
 * @since 2024-12-17
 */
@Service
public class CgnciReinsurerServiceImpl extends ServiceImpl<CgnciReinsurerMapper, CgnciReinsurerDO> implements CgnciReinsurerService {

    @Resource
    CgnciAccessoryService accessoryService;
    @Resource
    private CgnciReinsuranceRiskService cgnciReinsuranceRiskService;
    @Resource
    private CgnciReinsuranceRiskInsuredService cgnciReinsuranceRiskInsuredService;
    @Resource
    private CgnciReinsuranceRiskLayerService cgnciReinsuranceRiskLayerService;
    @Resource
    CgnciPaymentScheduleService paymentScheduleService;
    @Resource
    private CgnciEndorsementDetailService endorsementDetailService;

    @Override
    public List<CgnciReinsurerVO> listDivideInReinsurer(Long reinsuranceId) {
        List<CgnciReinsurerDO> divideInReinsurerDOList = this.list(new LambdaQueryWrapper<CgnciReinsurerDO>()
                .eq(CgnciReinsurerDO::getReinsuranceId, reinsuranceId));
        if (VerifyUtils.isEmpty(divideInReinsurerDOList)) {
            return null;
        }
        List<CgnciReinsurerVO> divideInReinsurerVOList = ConvertUtils.convert(divideInReinsurerDOList, CgnciReinsurerVO.class);
        List<Long> reinsurerIds = divideInReinsurerVOList.stream().map(CgnciReinsurerVO::getReinsurerId).collect(Collectors.toList());
        // 文件
        Map<Long, List<CgnciAccessoryVO>> accBusinessIdMap = new HashMap<>();
        List<CgnciAccessoryDO> accessoryDOList = accessoryService.list(new LambdaQueryWrapper<CgnciAccessoryDO>()
                .in(CgnciAccessoryDO::getBusinessId, reinsurerIds));
        if (VerifyUtils.isNotEmpty(accessoryDOList)) {
            List<CgnciAccessoryVO> accessoryVOList = ConvertUtils.convert(accessoryDOList, CgnciAccessoryVO.class);
            accBusinessIdMap = accessoryVOList.stream().collect(Collectors.groupingBy(CgnciAccessoryVO::getBusinessId));
        }

        // 分入险种
        Map<Long, List<CgnciReinsurerRiskVO>> reinsuranceIdMap = new HashMap<>();
        Map<Long, List<CgnciReinsurerRiskInsuredVO>> reinsuranceRiskInsuredIdMap = new HashMap<>();
        Map<Long, List<CgnciReinsurerRiskLayerVO>> reinsuranceRiskIdMap = new HashMap<>();
        Map<Long, List<CgnciAccessoryVO>> reinsuranceRiskLayerIdMap = new HashMap<>();

        List<CgnciReinsuranceRiskDO> divideInRiskSubDOList = cgnciReinsuranceRiskService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskDO>()
                .in(CgnciReinsuranceRiskDO::getReinsuranceId, reinsurerIds));
        if (VerifyUtils.isNotEmpty(divideInRiskSubDOList)) {
            List<CgnciReinsurerRiskVO> reinsuranceRiskVOList = ConvertUtils.convert(divideInRiskSubDOList, CgnciReinsurerRiskVO.class);
            List<Long> reinsuranceRiskIds = reinsuranceRiskVOList.stream().map(CgnciReinsurerRiskVO::getReinsuranceRiskId).collect(Collectors.toList());
            reinsuranceIdMap = reinsuranceRiskVOList.stream().collect(Collectors.groupingBy(CgnciReinsurerRiskVO::getReinsuranceId));

            // 分入险种标的
            List<CgnciReinsuranceRiskInsuredDO> insuredDOList = cgnciReinsuranceRiskInsuredService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskInsuredDO>()
                    .in(CgnciReinsuranceRiskInsuredDO::getReinsuranceRiskId, reinsuranceRiskIds));
            if (VerifyUtils.isNotEmpty(insuredDOList)) {
                List<CgnciReinsurerRiskInsuredVO> insuredVOList = ConvertUtils.convert(insuredDOList, CgnciReinsurerRiskInsuredVO.class);
                // 分入险种标的ID集合
                List<Long> insuredIds = insuredVOList.stream().map(CgnciReinsurerRiskInsuredVO::getRiskInsuredId).collect(Collectors.toList());
                reinsuranceRiskInsuredIdMap = insuredVOList.stream().collect(Collectors.groupingBy(CgnciReinsurerRiskInsuredVO::getReinsuranceRiskId));

                List<CgnciReinsuranceRiskLayerDO> divideInRiskLayerDOList = cgnciReinsuranceRiskLayerService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskLayerDO>()
                        .in(CgnciReinsuranceRiskLayerDO::getReinsuranceRiskId, insuredIds));
                if (VerifyUtils.isNotEmpty(divideInRiskLayerDOList)) {
                    // 分入险种层
                    List<CgnciReinsurerRiskLayerVO> divideInRiskLayerVOList = ConvertUtils.convert(divideInRiskLayerDOList, CgnciReinsurerRiskLayerVO.class);
                    // 分入险种层ID集合
                    List<Long> riskLayerIds = divideInRiskLayerVOList.stream().map(CgnciReinsurerRiskLayerVO::getLayerId).collect(Collectors.toList());
                    reinsuranceRiskIdMap = divideInRiskLayerVOList.stream().collect(Collectors.groupingBy(CgnciReinsurerRiskLayerVO::getReinsuranceRiskId));

                    // 查询免赔附件
                    List<CgnciAccessoryDO> accessoryDOList1 = accessoryService.list(new LambdaQueryWrapper<CgnciAccessoryDO>()
                            .in(CgnciAccessoryDO::getBusinessId, riskLayerIds));
                    if (VerifyUtils.isNotEmpty(accessoryDOList1)) {
                        List<CgnciAccessoryVO> accessoryVOList1 = ConvertUtils.convert(accessoryDOList1, CgnciAccessoryVO.class);
                        // 分入险种层根据分入险种标的id分组
                        reinsuranceRiskLayerIdMap = accessoryVOList1.stream().collect(Collectors.groupingBy(CgnciAccessoryVO::getBusinessId));
                    }
                }
            }
        }
        Map<Long, List<CgnciAccessoryVO>> finalAccBusinessIdMap = accBusinessIdMap;
        Map<Long, List<CgnciReinsurerRiskVO>> finalReinsuranceIdMap = reinsuranceIdMap;
        Map<Long, List<CgnciReinsurerRiskInsuredVO>> finalReinsuranceRiskInsuredIdMap = reinsuranceRiskInsuredIdMap;
        Map<Long, List<CgnciReinsurerRiskLayerVO>> finalReinsuranceRiskIdMap = reinsuranceRiskIdMap;
        Map<Long, List<CgnciAccessoryVO>> finalReinsuranceRiskLayerIdMap = reinsuranceRiskLayerIdMap;
        divideInReinsurerVOList.forEach(reinsurer -> {
            reinsurer.setAccessoryVO(VerifyUtils.isEmpty(finalAccBusinessIdMap.get(reinsurer.getReinsurerId())) ? null : finalAccBusinessIdMap.get(reinsurer.getReinsurerId()));
            if (VerifyUtils.isNotEmpty(finalReinsuranceIdMap)) {
                List<CgnciReinsurerRiskVO> reinsurerRiskVOList = finalReinsuranceIdMap.get(reinsurer.getReinsurerId());
                if (VerifyUtils.isNotEmpty(reinsurerRiskVOList)) {
                    reinsurerRiskVOList.forEach(risk -> {
                        if (VerifyUtils.isNotEmpty(finalReinsuranceRiskInsuredIdMap)) {
                            List<CgnciReinsurerRiskInsuredVO> riskInsuredVOS = finalReinsuranceRiskInsuredIdMap.get(risk.getReinsuranceRiskId());
                            if (VerifyUtils.isNotEmpty(riskInsuredVOS)) {
                                riskInsuredVOS.forEach(riskInsuredVO -> {
                                    if (VerifyUtils.isNotEmpty(finalReinsuranceRiskIdMap)) {
                                        List<CgnciReinsurerRiskLayerVO> riskLayerVOS = finalReinsuranceRiskIdMap.get(riskInsuredVO.getRiskInsuredId());
                                        if (VerifyUtils.isNotEmpty(riskLayerVOS)) {
                                            riskLayerVOS.forEach(riskLayerVO -> {
                                                if (VerifyUtils.isNotEmpty(finalReinsuranceRiskLayerIdMap)) {
                                                    List<CgnciAccessoryVO> accessoryVOS = finalReinsuranceRiskLayerIdMap.get(riskLayerVO.getLayerId());
                                                    riskLayerVO.setAccessoryVOList(accessoryVOS);
                                                }
                                            });
                                            riskInsuredVO.setRiskLayers(riskLayerVOS);
                                        }
                                    }
                                });
                                risk.setRiskInsureds(riskInsuredVOS);
                            }
                        }
                    });
                    reinsurer.setRisks(reinsurerRiskVOList);
                }
            }
        });
        return divideInReinsurerVOList;
    }

    @Override
    public List<CgnciReinsurerVO> listLfDivideOutReinsurer(Long reinsuranceId) {
        List<CgnciReinsurerDO> lfDivideOutReinsurerDOList = this.list(new LambdaQueryWrapper<CgnciReinsurerDO>()
                .eq(CgnciReinsurerDO::getReinsuranceId, reinsuranceId));
        if (VerifyUtils.isEmpty(lfDivideOutReinsurerDOList)) {
            return null;
        }
        List<CgnciReinsurerVO> lfDivideOutReinsurerVOList = ConvertUtils.convert(lfDivideOutReinsurerDOList, CgnciReinsurerVO.class);
        List<Long> reinsurerIds = lfDivideOutReinsurerVOList.stream().map(CgnciReinsurerVO::getReinsurerId).collect(Collectors.toList());
        // 文件
        Map<Long, List<CgnciAccessoryVO>> accBusinessIdMap = new HashMap<>();
        List<CgnciAccessoryDO> accessoryDOList = accessoryService.list(new LambdaQueryWrapper<CgnciAccessoryDO>()
                .in(CgnciAccessoryDO::getBusinessId, reinsurerIds));
        if (VerifyUtils.isNotEmpty(accessoryDOList)) {
            List<CgnciAccessoryVO> accessoryVOList = ConvertUtils.convert(accessoryDOList, CgnciAccessoryVO.class);
            accBusinessIdMap = accessoryVOList.stream().collect(Collectors.groupingBy(CgnciAccessoryVO::getBusinessId));
        }


        // 临分分出险种
        Map<Long, List<CgnciReinsurerRiskVO>> reinsuranceIdMap = new HashMap<>();
        Map<Long, List<CgnciReinsurerRiskInsuredVO>> reinsuranceInsuredIdMap = new HashMap<>();
        Map<Long, List<CgnciReinsurerRiskLayerVO>> reinsuranceRiskIdMap = new HashMap<>();
        List<CgnciReinsuranceRiskDO> lfDivideOutRiskDOList = cgnciReinsuranceRiskService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskDO>()
                .in(CgnciReinsuranceRiskDO::getReinsuranceId, reinsurerIds));
        if (VerifyUtils.isNotEmpty(lfDivideOutRiskDOList)) {
            List<CgnciReinsurerRiskVO> reinsuranceRiskVOList = ConvertUtils.convert(lfDivideOutRiskDOList, CgnciReinsurerRiskVO.class);
            List<Long> reinsuranceRiskIds = reinsuranceRiskVOList.stream().map(CgnciReinsurerRiskVO::getReinsuranceRiskId).collect(Collectors.toList());
            reinsuranceIdMap = reinsuranceRiskVOList.stream().collect(Collectors.groupingBy(CgnciReinsurerRiskVO::getReinsuranceId));

            // 临分分出险种标的
            List<CgnciReinsuranceRiskInsuredDO> insuredDOList = cgnciReinsuranceRiskInsuredService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskInsuredDO>()
                   .in(CgnciReinsuranceRiskInsuredDO::getReinsuranceRiskId, reinsuranceRiskIds));
            if (VerifyUtils.isNotEmpty(insuredDOList)) {
                List<CgnciReinsurerRiskInsuredVO> insuredVOList = ConvertUtils.convert(insuredDOList, CgnciReinsurerRiskInsuredVO.class);
                // 分入险种标的ID集合
                List<Long> reinsuranceRiskInsuredIds = insuredVOList.stream().map(CgnciReinsurerRiskInsuredVO::getRiskInsuredId).collect(Collectors.toList());
                // 分入险种标的ID和标的信息映射
                reinsuranceInsuredIdMap = insuredVOList.stream().collect(Collectors.groupingBy(CgnciReinsurerRiskInsuredVO::getReinsuranceRiskId));

                // 分入险种层
                List<CgnciReinsuranceRiskLayerDO> divideInRiskLayerDOList = cgnciReinsuranceRiskLayerService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskLayerDO>()
                      .in(CgnciReinsuranceRiskLayerDO::getReinsuranceRiskId, reinsuranceRiskInsuredIds));
                if (VerifyUtils.isNotEmpty(divideInRiskLayerDOList)) {
                    List<CgnciReinsurerRiskLayerVO> divideInRiskLayerVOList = ConvertUtils.convert(divideInRiskLayerDOList, CgnciReinsurerRiskLayerVO.class);
                    reinsuranceRiskIdMap = divideInRiskLayerVOList.stream().collect(Collectors.groupingBy(CgnciReinsurerRiskLayerVO::getReinsuranceRiskId));
                }
            }
        }

        // 缴费期次
        Map<Long, List<CgnciPaymentScheduleVO>> paymentIdMap = new HashMap<>();
        List<CgnciPaymentScheduleDO> paymentScheduleList = paymentScheduleService.list(new LambdaQueryWrapper<CgnciPaymentScheduleDO>()
                .in(CgnciPaymentScheduleDO::getReinsuranceId, reinsurerIds)
                .orderByAsc(CgnciPaymentScheduleDO::getPaymentPeriod));
        if (VerifyUtils.isNotEmpty(paymentScheduleList)) {
            List<CgnciPaymentScheduleVO> paymentScheduleVO = ConvertUtils.convert(paymentScheduleList, CgnciPaymentScheduleVO.class);
            paymentIdMap = paymentScheduleVO.stream().collect(Collectors.groupingBy(CgnciPaymentScheduleVO::getReinsuranceId));
        }

        // 保费变化量
        Map<Long, List<CgnciEndorsementDetailVO>> endorsementDetailIdMap = new HashMap<>();
        Map<Long, List<CgnciPaymentScheduleVO>> endorsementPaymentIdMap = new HashMap<>();
        List<CgnciEndorsementDetailDO> endorsementDetailDOList = endorsementDetailService.list(new LambdaQueryWrapper<CgnciEndorsementDetailDO>()
                .in(CgnciEndorsementDetailDO::getReinsurerId, reinsurerIds));
        if (VerifyUtils.isNotEmpty(endorsementDetailDOList)) {
            List<CgnciEndorsementDetailVO> endorsementDetailVOList = ConvertUtils.convert(endorsementDetailDOList, CgnciEndorsementDetailVO.class);
            endorsementDetailIdMap = endorsementDetailVOList.stream().collect(Collectors.groupingBy(CgnciEndorsementDetailVO::getReinsurerId));
            List<Long> detailIds = endorsementDetailVOList.stream().map(CgnciEndorsementDetailVO::getDetailId).collect(Collectors.toList());
            List<CgnciPaymentScheduleDO> endorsementPaymentDOList = paymentScheduleService.list(new LambdaQueryWrapper<CgnciPaymentScheduleDO>()
                    .in(CgnciPaymentScheduleDO::getReinsuranceId, detailIds)
                    .orderByAsc(CgnciPaymentScheduleDO::getPaymentPeriod));
            if (VerifyUtils.isNotEmpty(endorsementPaymentDOList)) {
                // 分入险种层
                List<CgnciPaymentScheduleVO> endorsementPaymentScheduleVO = ConvertUtils.convert(endorsementPaymentDOList, CgnciPaymentScheduleVO.class);
                endorsementPaymentIdMap = endorsementPaymentScheduleVO.stream().collect(Collectors.groupingBy(CgnciPaymentScheduleVO::getReinsuranceId));
            }
        }

        // 组装VO
        Map<Long, List<CgnciAccessoryVO>> finalAccBusinessIdMap = accBusinessIdMap;
        Map<Long, List<CgnciReinsurerRiskVO>> finalReinsuranceIdMap = reinsuranceIdMap;
        Map<Long, List<CgnciReinsurerRiskInsuredVO>> finalReinsuranceInsuredIdMap = reinsuranceInsuredIdMap;
        Map<Long, List<CgnciReinsurerRiskLayerVO>> finalReinsuranceRiskIdMap = reinsuranceRiskIdMap;
        Map<Long, List<CgnciPaymentScheduleVO>> finalPaymentIdMap = paymentIdMap;
        Map<Long, List<CgnciEndorsementDetailVO>> finalEndorsementDetailIdMap = endorsementDetailIdMap;
        Map<Long, List<CgnciPaymentScheduleVO>> finalEndorsementPaymentIdMap = endorsementPaymentIdMap;
        lfDivideOutReinsurerVOList.forEach(reinsurer -> {
            // 文件
            reinsurer.setAccessoryVO(VerifyUtils.isEmpty(finalAccBusinessIdMap.get(reinsurer.getReinsurerId())) ? null : finalAccBusinessIdMap.get(reinsurer.getReinsurerId()));
            // 分出险种
            if (VerifyUtils.isNotEmpty(finalReinsuranceIdMap)) {
                List<CgnciReinsurerRiskVO> reinsurerRiskVOList = finalReinsuranceIdMap.get(reinsurer.getReinsurerId());
                if (VerifyUtils.isNotEmpty(reinsurerRiskVOList)) {
                    reinsurerRiskVOList.forEach(risk -> {
                        if (VerifyUtils.isNotEmpty(finalReinsuranceInsuredIdMap)) {
                            List<CgnciReinsurerRiskInsuredVO> riskInsureds = finalReinsuranceInsuredIdMap.get(risk.getReinsuranceRiskId());
                            if (VerifyUtils.isNotEmpty(riskInsureds)) {
                                riskInsureds.forEach(riskInsured -> {
                                    if (VerifyUtils.isNotEmpty(finalReinsuranceRiskIdMap)) {
                                        riskInsured.setRiskLayers(finalReinsuranceRiskIdMap.get(riskInsured.getRiskInsuredId()));
                                    }
                                });
                                risk.setRiskInsureds(riskInsureds);
                            }
                        }
                    });
                }
                reinsurer.setRisks(reinsurerRiskVOList);
            }

            // 缴费期次
            if (VerifyUtils.isNotEmpty(finalPaymentIdMap)) {
                reinsurer.setPayments(finalPaymentIdMap.get(reinsurer.getReinsurerId()));
            }

            // 保费变化率
            if (VerifyUtils.isNotEmpty(finalEndorsementDetailIdMap)) {
                List<CgnciEndorsementDetailVO> endorsementDetailVOList = finalEndorsementDetailIdMap.get(reinsurer.getReinsurerId());
                if (CollectionUtils.isNotEmpty(endorsementDetailVOList)) {
                    endorsementDetailVOList.forEach(endorsementDetail -> {
                        if (VerifyUtils.isNotEmpty(finalEndorsementPaymentIdMap)) {
                            endorsementDetail.setPayments(finalEndorsementPaymentIdMap.get(endorsementDetail.getReinsurerId()));
                        }
                        reinsurer.setEndorsementDetailVO(endorsementDetail);
                    });
                }

            }
        });
        return lfDivideOutReinsurerVOList;
    }

    @Override
    public void updateReinsurerColumn(List<CgnciReinsuranceRiskInsuredDO> divideInReinsurerRiskInsuredDOS, CgnciReinsurerDO reinsurer, Long layerId) {
        // 查询分出--再保人--险种层
        List<CgnciReinsuranceRiskLayerDO> layers = cgnciReinsuranceRiskLayerService.list(new LambdaQueryWrapper<CgnciReinsuranceRiskLayerDO>()
                .in(CgnciReinsuranceRiskLayerDO::getReinsuranceRiskId, divideInReinsurerRiskInsuredDOS.stream().map(CgnciReinsuranceRiskInsuredDO::getRiskInsuredId).collect(Collectors.toList()))
                .eq(VerifyUtils.isNotEmpty(layerId), CgnciReinsuranceRiskLayerDO::getLayerId, layerId));
        // 分入毛保费
        BigDecimal grossPremium = BeanUtils.sumBigDecimalProperty(layers, CgnciReinsuranceRiskLayerDO::getGrossPremium);
        // 分入手续费
        BigDecimal commission = BeanUtils.sumBigDecimalProperty(layers, CgnciReinsuranceRiskLayerDO::getCommission);
        // 分入净保费
        BigDecimal netPremium = BeanUtils.sumBigDecimalProperty(layers, CgnciReinsuranceRiskLayerDO::getNetPremium);
        // 分入再保经纪费
        BigDecimal brokerFee = BeanUtils.sumBigDecimalProperty(layers, CgnciReinsuranceRiskLayerDO::getBrokerFee);
        // 更新分出--再保人汇总字段
        if (VerifyUtils.isNotEmpty(reinsurer.getEngagedGrossPremium())) {
            reinsurer.setEngagedGrossPremium(reinsurer.getEngagedGrossPremium().subtract(grossPremium));
        }

        if (VerifyUtils.isNotEmpty(reinsurer.getEngagedCommission())) {
            reinsurer.setEngagedCommission(reinsurer.getEngagedCommission().subtract(commission));
        }

        if (VerifyUtils.isNotEmpty(reinsurer.getEngagedNetPremium())) {
            reinsurer.setEngagedNetPremium(reinsurer.getEngagedNetPremium().subtract(netPremium));
        }

        if (VerifyUtils.isNotEmpty(reinsurer.getEngagedEconomy())) {
            reinsurer.setEngagedEconomy(reinsurer.getEngagedEconomy().subtract(brokerFee));
        }
        this.updateById(reinsurer);
    }
}
